
#include "SliderMidiInputAdapter.h"

#include "MainWindow.h"
#include "OutputWindow.h"

namespace SliderMidiAction
{
	static MainWindow *mw;
	
	class BlackButton : public MidiInputAction
	{
		QString id() { return "64258ee6-f50e-4f94-ad6a-589a93ac2d40"; }
		QString name() { return "Black Mains"; }
		void trigger(int)
		{
			mw->toggleBlack();	
		}
	};
	
	class PlayPresetButton : public MidiInputAction
	{
	public:
		PlayPresetButton(LightingPreset *preset, int num) 
			: MidiInputAction()
			, m_num(num)
		{
			m_preset = preset; 
		}
		
		QString id() { return tr("ad44323f-22a2-43a5-9839-1d6476b5ca41-%1").arg(m_num); }
		QString name() { return tr("Run Preset \"%1\"").arg(m_preset->name()); }
		void trigger(int)
		{
			mw->playPreset(m_preset);
		}
		
		
	protected:
		LightingPreset *m_preset;
		int m_num;
	};
	
	class PresetFader : public MidiInputAction
	{
	public:
		PresetFader(LightingPreset *preset, int num) 
			: MidiInputAction()
			, m_num(num)
		{
			m_preset = preset; 
		}
		
		QString id() { return tr("fb7a5663-7c8f-432b-991c-901cbf3223af-%1").arg(m_num); }
		QString name() { return tr("Preset Fader for \"%1\"").arg(m_preset->name()); }
		void trigger(int value)
		{
			// 127 is max for my MIDI fader
			double percent = ((double)value) / 127.0;
			// function we'll call expects an integer percent from 0-255 
			double ouputValue = 255.0 * percent;
			
			m_preset->setValue((int)ouputValue);
		}
		
		bool isFader() { return true; }
		
	protected:
		LightingPreset *m_preset;
		int m_num;
	};
	
	
	class DmxChannelFader : public MidiInputAction
	{
	public:
		DmxChannelFader(DmxChannel *chan) 
			: MidiInputAction()
			, m_chan(chan)
		{
			//qDebug() << "DmxChannelFader: "<<chan->name();
		}
		
		QString id() { return tr("e99f7bb5-271f-4203-bd87-6b2c609279de-%1").arg(m_chan->dmxNum()); }
		QString name() { return tr("Output Fader for \"%1\"").arg(m_chan->name().isEmpty() ? tr("Unabled Channel %1").arg(m_chan->num()) : m_chan->name()); }
		void trigger(int value)
		{
			// 127 is max for my MIDI fader
			double percent = ((double)value) / 127.0;
			// function we'll call expects an integer percent from 0-255 
			double ouputValue = 255.0 * percent;
			
			m_chan->setValue((int)ouputValue);
		}
		
		bool isFader() { return true; }
		
	protected:
		DmxChannel *m_chan;
	};
	
	class MainsFader : public MidiInputAction
	{
		QString id() { return "b0f8f64b-96f3-4d6f-9084-e9f145b37e0b"; }
		QString name() { return "Set Mains Value"; }
		void trigger(int value)
		{
			// 127 is max for my MIDI fader
			double percent = ((double)value) / 127.0;
			// function we'll call expects an integer percent from 0-255 
			double outputValue = 255.0 * percent;
			
			mw->setMainLevel((int)outputValue);
		}
		bool isFader() { return true; }
	};
	
	class FadeSpeedFader : public MidiInputAction
	{
		QString id() { return "1188e63f-4723-424c-b5fc-a1068da669c7"; }
		QString name() { return "Set Fade Speed"; }
		bool isFader() { return true; }
		void trigger(int value)
		{
			// 127 is max for my MIDI fader
			double percent = ((double)value) / 127.0;
			// setFadeSpeed() expects an integer percent from 0-1000 ms 
			double speed = 10000.0 * percent;
			
			mw->setFadeSpeed((int)speed);	
		}
	};
};

void SliderMidiInputAdapter::setupActionList()
{
	MainWindow *mw = SliderMidiAction::mw = MainWindow::inst();
	
	m_actionList.clear();
	
	m_actionList
		<< new SliderMidiAction::BlackButton()
		<< new SliderMidiAction::MainsFader()
		<< new SliderMidiAction::FadeSpeedFader();
		
	QList<LightingPreset*> presetList = mw->presets();
	int counter=0;
	foreach(LightingPreset *preset, presetList)
	{
		m_actionList << new SliderMidiAction::PlayPresetButton(preset, counter)
		             << new SliderMidiAction::PresetFader(preset, counter);
		counter ++;
	}
	
	DmxChannelList channelList = mw->outputWindow()->channelList();
	foreach(DmxChannel *chan, channelList)
		m_actionList << new SliderMidiAction::DmxChannelFader(chan);
	
	
	qDebug() << "SliderMidiInputAdapter::setupActionList(): Added "<<m_actionList.size() <<" actions to the MIDI Action List";
}

SliderMidiInputAdapter *SliderMidiInputAdapter::m_inst = 0;

SliderMidiInputAdapter::SliderMidiInputAdapter()
	: MidiInputAdapter()
{
	setupActionList();
	loadSettings();
}

SliderMidiInputAdapter *SliderMidiInputAdapter::instance()
{
	if(!m_inst)
		m_inst = new SliderMidiInputAdapter();
	return m_inst;
}
